home *** CD-ROM | disk | FTP | other *** search
/ Assassins - Ultimate CD Games Collection 4 / Assassins 4 (1999)(Weird Science).iso / misc / omega / source / gen1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-02  |  17.4 KB  |  613 lines

  1. /* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
  2. /* gen1.c */
  3. /* level generator functions */
  4.  
  5. #include "glob.h"
  6.  
  7.  
  8. /* Deallocate current dungeon */
  9. void free_dungeon()
  10. {
  11. #ifndef SAVE_LEVELS
  12.   plv tlv;
  13.   
  14.   while (Dungeon != NULL) {
  15.     tlv = Dungeon;
  16.     Dungeon = Dungeon->next;
  17.     free_level(tlv);
  18.   }
  19. #else
  20.   if (Dungeon != NULL)
  21.   {
  22.     sprintf(Str2,"om%d*.lev",Dungeon->environment);
  23.     kill_levels(Str2);
  24.   }
  25. #endif
  26. }
  27.  
  28.  
  29. /* erase the level w/o deallocating it*/
  30. void clear_level(dungeon_level)
  31. struct level *dungeon_level;
  32. {
  33.   int i,j;
  34.   if (dungeon_level != NULL) {
  35.     dungeon_level->generated = FALSE;
  36.     dungeon_level->numrooms = 0;
  37.     dungeon_level->tunnelled = 0;
  38.     dungeon_level->depth = 0;
  39.     dungeon_level->mlist = NULL;
  40.     dungeon_level->next = NULL;
  41.     dungeon_level->last_visited = time((long *) NULL);
  42.     for(i=0;i<MAXWIDTH;i++)
  43.       for(j=0;j<MAXLENGTH;j++) {
  44.     dungeon_level->site[i][j].locchar = WALL;
  45.     dungeon_level->site[i][j].showchar = SPACE;
  46.     dungeon_level->site[i][j].creature = NULL;
  47.     dungeon_level->site[i][j].things = NULL;
  48.     dungeon_level->site[i][j].aux = difficulty()*20;
  49.     dungeon_level->site[i][j].buildaux = 0;
  50.     dungeon_level->site[i][j].p_locf = L_NO_OP;
  51.     dungeon_level->site[i][j].lstatus = 0;
  52.     dungeon_level->site[i][j].roomnumber = RS_WALLSPACE;
  53.       }
  54.   }
  55. }
  56.  
  57.  
  58.  
  59. /* Looks for level tolevel in current dungeon which is named by
  60. Dungeon, which may be NULL. If the level is found, and rewrite_level
  61. is FALSE, and the level has already been generated, nothing happens
  62. beyond Level being set correctly. Otherwise the level is recreated
  63. from scratch */
  64.  
  65. void change_level(fromlevel,tolevel,rewrite_level)
  66. char fromlevel,tolevel,rewrite_level;
  67. {
  68.   struct level *thislevel = NULL;
  69.   Player.sx = -1; Player.sy = -1; /* sanctuary effect dispelled */
  70. #ifndef SAVE_LEVELS
  71.   thislevel = findlevel(Dungeon,tolevel);
  72.   deepest[Current_Environment] = max(deepest[Current_Environment],tolevel);
  73.   if (thislevel == NULL) {
  74.     thislevel = ((plv) checkmalloc(sizeof(levtype)));
  75. #else
  76.   thislevel = msdos_changelevel(Level,Current_Environment,tolevel);
  77.   deepest[Current_Environment] = max(deepest[Current_Environment],tolevel);
  78.   if (thislevel == NULL) {
  79.     thislevel = &TheLevel;
  80. #endif
  81.     clear_level(thislevel);
  82.     Level = thislevel;
  83.     Level->next = Dungeon;
  84.     Dungeon = Level;
  85.   }
  86.   Level = thislevel;
  87.   if ((! Level->generated) || rewrite_level) {
  88.     initrand(Current_Environment, tolevel);
  89.     Level->environment = Current_Environment;
  90.     Level->depth = tolevel;
  91.     Level->generated = TRUE;
  92.     switch(Current_Environment) {
  93.     case E_CAVES: 
  94.       if ((random_range(4)==0) && (tolevel < MaxDungeonLevels))
  95.     room_level();
  96.       else cavern_level();
  97.       break;
  98.     case E_SEWERS: 
  99.       if ((random_range(4)==0) && (tolevel < MaxDungeonLevels))
  100.     room_level();
  101.       else sewer_level(); 
  102.       break;
  103.     case E_CASTLE:
  104.       room_level();
  105.       break;
  106.     case E_ASTRAL:
  107.       maze_level();
  108.       break;
  109.     case E_VOLCANO:
  110.       switch(random_range(3)) {
  111.       case 0: cavern_level(); break;
  112.       case 1: room_level(); break;
  113.       case 2: maze_level(); break;
  114.       }
  115.       break;
  116.     default: print3("This dungeon not implemented!"); break;
  117.     }
  118.     install_traps();
  119.     install_specials();
  120.     make_stairs(fromlevel);
  121.     make_stairs(fromlevel);
  122.     initrand(-2, 0);
  123.     populate_level(Current_Environment);
  124.     stock_level();
  125.   }
  126.   find_stairs(fromlevel,tolevel);
  127.   ScreenOffset = Player.y - (ScreenLength/2);
  128.   show_screen();
  129.   screencheck(Player.y);
  130.   drawvision(Player.x,Player.y);
  131.   /* synchronize with player on level change */
  132.   Player.click = (Tick+1)%60;
  133.   roomcheck();
  134. }
  135.  
  136.  
  137. #ifndef SAVE_LEVELS
  138. /* tries to find the level of depth levelnum in dungeon; if can't find
  139.    it returns NULL */
  140. plv findlevel(dungeon,levelnum)
  141. struct level *dungeon;
  142. char levelnum;
  143. {
  144.   if (dungeon == NULL) return(NULL);
  145.   else {
  146.     while((dungeon->next != NULL) && (dungeon->depth != levelnum))
  147.       dungeon = dungeon->next;
  148.     if (dungeon->depth == levelnum) {
  149.       dungeon->last_visited = time((long *)NULL);
  150.       return(dungeon);
  151.     }
  152.     else return(NULL);
  153.   }
  154. }
  155. #endif
  156.  
  157.  
  158.  
  159. /* keep going in one orthogonal direction or another until we hit our */
  160. /* destination */
  161.  
  162. void straggle_corridor(fx,fy,tx,ty,loc,rsi)
  163. int fx,fy,tx,ty;
  164. short loc;
  165. char rsi;
  166. {
  167.   int dx,dy;
  168.   while ((fx != tx) || (fy != ty)) {
  169.     dx = tx - fx;
  170.     dy = ty - fy;
  171.     if (random_range(abs(dx)+abs(dy)) < abs(dx))
  172.       corridor_crawl(&fx,&fy,sign(dx),0,random_range(abs(dx))+1,loc,rsi);
  173.     else corridor_crawl(&fx,&fy,0,sign(dy),random_range(abs(dy))+1,loc,rsi);
  174.   }
  175. }
  176.  
  177.  
  178.  
  179. void makedoor(x,y)
  180. int x,y;
  181. {
  182.   if (random_range(20) <= Level->depth/10) {
  183.     Level->site[x][y].locchar = FLOOR;
  184.     lset(x,y,SECRET);
  185.   }
  186.   else if (random_range(20)<=Level->depth/2) {
  187.     Level->site[x][y].locchar = CLOSED_DOOR;
  188.     if (random_range(20) <= Level->depth/10) 
  189.       lset(x,y,SECRET);
  190.     if (random_range(40) <= Level->depth) 
  191.       Level->site[x][y].aux = LOCKED;
  192.     else Level->site[x][y].aux = UNLOCKED;
  193.   }
  194.   else {
  195.     Level->site[x][y].locchar = OPEN_DOOR;
  196.     Level->site[x][y].aux = UNLOCKED;
  197.   }
  198.   if (! loc_statusp(x,y,SECRET)) {
  199.     lset(x,y+1,STOPS);
  200.     lset(x+1,y,STOPS);
  201.     lset(x-1,y,STOPS);
  202.     lset(x,y-1,STOPS);
  203.   }
  204.   Level->site[x][y].p_locf = L_NO_OP; 
  205.   /* prevents water corridors from being instant death in sewers */
  206. }
  207.  
  208.  
  209. void corridor_crawl(fx,fy,sx,sy,n,loc,rsi)
  210. int *fx,*fy,sx,sy,n;
  211. short loc;
  212. char rsi;
  213. {
  214.   int i;
  215.   for (i=0;i<n;i++) {
  216.     *fx += sx;
  217.     *fy += sy;
  218.     if ((*fx < WIDTH) && 
  219.     (*fx > -1) && 
  220.     (*fy > -1) && 
  221.     (*fy < LENGTH)) {
  222.       Level->site[*fx][*fy].locchar = loc;
  223.       if (Level->site[*fx][*fy].roomnumber == RS_WALLSPACE)
  224.     Level->site[*fx][*fy].roomnumber = rsi;
  225.       if (loc==WATER) 
  226.     Level->site[*fx][*fy].p_locf = L_WATER;
  227.       else if (loc==FLOOR) 
  228.     Level->site[*fx][*fy].p_locf = L_NO_OP;
  229.       else if (loc==RUBBLE)
  230.     Level->site[*fx][*fy].p_locf = L_RUBBLE;
  231.     }
  232.   }
  233. }  
  234.  
  235.  
  236.  
  237.  
  238.  
  239. char *roomname(index)
  240. int index;
  241. {
  242.   switch(index) {
  243.   case RS_ZORCH:strcpy(Str4,"A place zorched by powerful magic.");break;
  244.   case RS_COURT:strcpy(Str4,"The Court of the ArchMage."); break;
  245.   case RS_CIRCLE:strcpy(Str4,"The Astral Demesne of the Circle of Sorcerors");
  246.     break;
  247.   case RS_MAGIC_ISLE: strcpy(Str4,"An island positively reeking of magic");
  248.     break;
  249.   case RS_STARPEAK: strcpy(Str4,"Near the oddly glowing peak of a mountain");
  250.     break;
  251.   case RS_VOLCANO: strcpy(Str4,"Deep within the bowels of the earth"); break;
  252.   case RS_HIGHASTRAL: strcpy(Str4,"The High Astral Plane"); break;
  253.   case RS_EARTHPLANE: strcpy(Str4,"The Plane of Earth"); break;
  254.   case RS_WATERPLANE: strcpy(Str4,"The Plane of Water"); break;
  255.   case RS_FIREPLANE: strcpy(Str4,"The Plane of Fire"); break;
  256.   case RS_AIRPLANE: strcpy(Str4,"The Plane of Air"); break;
  257.   case RS_KITCHEN: strcpy(Str4,"A kitchen"); break;
  258.   case RS_BATHROOM: strcpy(Str4,"A bathroom"); break;
  259.   case RS_BEDROOM: strcpy(Str4,"A bedroom"); break;
  260.   case RS_DININGROOM: strcpy(Str4,"A dining room"); break;
  261.   case RS_SECRETPASSAGE: strcpy(Str4,"A secret passage"); break;
  262.   case RS_CLOSET: strcpy(Str4,"A stuffy closet"); break;
  263.   case RS_ARENA: strcpy(Str4,"The Rampart Arena"); break;
  264.   case RS_DROWNED_SEWER: strcpy(Str4,"A water-filled sewer node"); break;
  265.   case RS_DRAINED_SEWER: strcpy(Str4,"An unused sewer node"); break;
  266.   case RS_SEWER_DUCT: strcpy(Str4,"A winding sewer duct"); break;
  267.   case RS_DESTINY: strcpy(Str4,"The Halls of Fate"); break;
  268.   case RS_DRUID: strcpy(Str4,"The Great Henge"); break;
  269.   case RS_HECATE: strcpy(Str4,"The Church of the Far Side"); break;
  270.   case RS_SET: strcpy(Str4,"The Temple of the Black Hand"); break;
  271.   case RS_ATHENA: strcpy(Str4,"The Parthenon"); break;
  272.   case RS_ODIN: strcpy(Str4,"The Shrine of the Noose"); break;
  273.   case RS_ADEPT: strcpy(Str4,"The Adept's Challenge"); break;
  274.   case RS_WYRM: strcpy(Str4,"The Sunken Cavern of the Great Wyrm."); break;
  275.   case RS_OCEAN: strcpy(Str4,"The Underground Ocean."); break;
  276.   case RS_PONDS: strcpy(Str4,"A series of subterranean pools and streams."); break;
  277.   case RS_DRAGONLORD: strcpy(Str4,"The Lair of the DragonLord."); break;
  278.   case RS_GOBLINKING: strcpy(Str4,"The Caves of the Goblins."); break;
  279.   case RS_CAVERN: strcpy(Str4,"A vast natural cavern."); break;
  280.   case RS_CORRIDOR: strcpy(Str4,"A dimly lit corridor."); break;
  281.   case RS_WALLSPACE: strcpy(Str4,"A niche hollowed out of the wall."); break;
  282.   case ROOMBASE+0: strcpy(Str4,"An abandoned garderobe."); break;
  283.   case ROOMBASE+1: strcpy(Str4,"A dungeon cell."); break;
  284.   case ROOMBASE+2: strcpy(Str4,"A tiled chamber."); break;
  285.   case ROOMBASE+3: strcpy(Str4,"A crystal cavern."); break;
  286.   case ROOMBASE+4: strcpy(Str4,"Someone's bedroom."); break;
  287.   case ROOMBASE+5: strcpy(Str4,"An old storeroom."); break;
  288.   case ROOMBASE+6: strcpy(Str4,"A room with charred walls."); break;
  289.   case ROOMBASE+7: strcpy(Str4,"A marble hall."); break;
  290.   case ROOMBASE+8: strcpy(Str4,"An eerie cave."); break;
  291.   case ROOMBASE+9: strcpy(Str4,"A ransacked treasure-chamber."); break;
  292.   case ROOMBASE+10: strcpy(Str4,"A smoke-filled room."); break;
  293.   case ROOMBASE+11: strcpy(Str4,"A well-appointed apartment."); break;
  294.   case ROOMBASE+12: strcpy(Str4,"An antechamber."); break;
  295.   case ROOMBASE+13: strcpy(Str4,"An unoccupied harem."); break;
  296.   case ROOMBASE+14: strcpy(Str4,"A multi-purpose room."); break;
  297.   case ROOMBASE+15: strcpy(Str4,"A room filled with stalactites."); break;
  298.   case ROOMBASE+16: strcpy(Str4,"An underground greenhouse."); break;
  299.   case ROOMBASE+17: strcpy(Str4,"A water closet."); break;
  300.   case ROOMBASE+18: strcpy(Str4,"A study."); break;
  301.   case ROOMBASE+19: strcpy(Str4,"A living room."); break;
  302.   case ROOMBASE+20: strcpy(Str4,"A comfortable den."); break;
  303.   case ROOMBASE+21: strcpy(Str4,"An abatoir."); break;
  304.   case ROOMBASE+22: strcpy(Str4,"A boudoir.");break;
  305.   case ROOMBASE+23: strcpy(Str4,"A star chamber.");break;
  306.   case ROOMBASE+24: strcpy(Str4,"A manmade cavern."); break;
  307.   case ROOMBASE+25: strcpy(Str4,"A sewer control room");break;
  308.   case ROOMBASE+26: strcpy(Str4,"A shrine to High Magic"); break;
  309.   case ROOMBASE+27: strcpy(Str4,"A magic laboratory"); break;
  310.   case ROOMBASE+28: strcpy(Str4,"A room with inscribed pentagram");break;
  311.   case ROOMBASE+29: strcpy(Str4,"A chamber with a blue crystal omega dais");
  312.     break;
  313.   default: strcpy(Str4,"A room of mystery and allure."); break;
  314.   }
  315.   return(Str4);
  316. }
  317.  
  318.  
  319.  
  320. /* puts the player on the first set of stairs from the apt level */
  321. /* if can't find them, just drops player anywhere.... */
  322. void find_stairs(fromlevel,tolevel)
  323. char fromlevel;
  324. char tolevel;
  325. {
  326.   int i,j,found=FALSE;
  327.   short sitechar;
  328.   if (fromlevel > tolevel) sitechar = STAIRS_DOWN; else sitechar = STAIRS_UP;
  329.   for(i=0;i<WIDTH;i++)
  330.     for(j=0;j<LENGTH;j++) 
  331.       if ((Level->site[i][j].locchar == sitechar) && (! found)) { 
  332.     found = TRUE;
  333.     Player.x = i;
  334.     Player.y = j;
  335.     break;
  336.       }
  337.   if (! found) {
  338.     findspace(&Player.x,&Player.y,-1);
  339.     if (Level->environment != E_ASTRAL) {
  340.       Level->site[Player.x][Player.y].locchar = sitechar;
  341.       lset(Player.x, Player.y, CHANGED);
  342.     }
  343.   }
  344. }
  345.  
  346.  
  347.  
  348. void install_traps()
  349. {
  350.   int i,j;
  351.   for(i=0;i<WIDTH;i++)
  352.     for(j=0;j<LENGTH;j++)
  353.       if ((Level->site[i][j].locchar == FLOOR) &&
  354.       (Level->site[i][j].p_locf == L_NO_OP) &&
  355.       random_range(500) <= ((int)(Level->depth/6)))
  356.     Level->site[i][j].p_locf = TRAP_BASE+random_range(NUMTRAPS);
  357. }
  358.  
  359.  
  360.  
  361. /* x, y, is top left corner, l is length of side, rsi is room string index */
  362. /* baux is so all rooms will have a key field. */
  363. void build_square_room(x,y,l,rsi,baux)
  364. int x,y,l;
  365. char rsi;
  366. int baux;
  367. {
  368.   int i,j;
  369.  
  370.   for(i=x;i<=x+l;i++)
  371.     for(j=y;j<=y+l;j++){
  372.       Level->site[i][j].roomnumber = rsi;
  373.       Level->site[i][j].buildaux = baux;
  374.     }
  375.   for(i=x+1;i<x+l;i++)
  376.     for(j=y+1;j<y+l;j++) {
  377.       Level->site[i][j].locchar = FLOOR;
  378.       Level->site[i][j].p_locf = L_NO_OP;
  379.     }
  380. }
  381.  
  382.  
  383.  
  384. void build_room(x,y,l,rsi,baux)
  385. int x,y,l;
  386. char rsi;
  387. int baux;
  388. {
  389.   build_square_room(x,y,l,rsi,baux);
  390. }
  391.  
  392. void cavern_level()
  393. {
  394.   int i,fx,fy,tx,ty,t,l,e;
  395.   char rsi;
  396.  
  397.   Level->numrooms = 1;
  398.  
  399.   if ((Current_Dungeon == E_CAVES) && (Level->depth == CAVELEVELS))
  400.     rsi = RS_GOBLINKING;
  401.   else rsi = RS_CAVERN;
  402.   t = random_range(LENGTH/2);
  403.   l = random_range(WIDTH/2);
  404.   e = random_range(WIDTH/8)+WIDTH/8;
  405.   build_square_room(t,l,e,rsi,0);
  406.   
  407.   for (i=0;i<16;i++) {
  408.     findspace(&tx,&ty,-1);
  409.     fx = random_range(WIDTH-2)+1;
  410.     fy = random_range(LENGTH-2)+1;
  411.     straggle_corridor(fx,fy,tx,ty,FLOOR,RS_CORRIDOR);
  412.   }
  413.   while (random_range(3)==1) {
  414.     findspace(&tx,&ty,-1);
  415.     fx = random_range(WIDTH-2)+1;
  416.     fy = random_range(LENGTH-2)+1;
  417.     straggle_corridor(fx,fy,tx,ty,WATER,RS_PONDS);
  418.   }
  419.   if (Current_Dungeon == E_CAVES) {
  420.     if ((Level->depth == CAVELEVELS) && (! gamestatusp(COMPLETED_CAVES))) {
  421.       findspace(&tx,&ty,-1);
  422.       Level->mlist = ((pml) checkmalloc(sizeof(mltype)));
  423.       Level->mlist->next = NULL;
  424.       Level->mlist->m = 
  425.     Level->site[tx][ty].creature = 
  426.       ((pmt) make_creature(ML3+5)); /* goblin king */
  427.       Level->mlist->m->x = tx;
  428.       Level->mlist->m->y = ty;
  429.     }
  430.   }
  431.   else if (Current_Environment == E_VOLCANO) {
  432.     if (Level->depth == VOLCANOLEVELS) {
  433.       findspace(&tx,&ty,-1);
  434.       Level->mlist = ((pml) checkmalloc(sizeof(mltype)));
  435.       Level->mlist->next = NULL;
  436.       Level->mlist->m = 
  437.     Level->site[tx][ty].creature = 
  438.       ((pmt) make_creature(ML10+4)); /* The dark emp */
  439.       Level->mlist->m->x = tx;
  440.       Level->mlist->m->y = ty;
  441.     }
  442.   }
  443. }
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451. void sewer_level()
  452. {
  453.   int i,tx,ty,t,l,e;
  454.   char rsi;
  455.   short lchar;
  456.  
  457.   Level->numrooms = random_range(3)+3;
  458.   rsi = RS_DRAINED_SEWER;
  459.   for (i=0;i<Level->numrooms;i++) {
  460.     do {
  461.       t = random_range(LENGTH-10)+1;
  462.       l = random_range(WIDTH-10)+1;
  463.       e = 4;
  464.     } while ((Level->site[l][t].roomnumber == rsi) ||
  465.          (Level->site[l+e][t].roomnumber == rsi) ||
  466.          (Level->site[l][t+e].roomnumber == rsi) ||
  467.          (Level->site[l+e][t+e].roomnumber == rsi));
  468.     if (random_range(5)) {
  469.       lchar = FLOOR;
  470.       rsi = RS_DRAINED_SEWER;
  471.     }
  472.     else {
  473.       lchar = WATER;
  474.       rsi = RS_DROWNED_SEWER;
  475.     }
  476.     build_room(l,t,e,rsi,i);
  477.     sewer_corridor(l,t,-1,-1,lchar);
  478.     sewer_corridor(l+e,t,1,-1,lchar);
  479.     sewer_corridor(l,t+e,-1,1,lchar);
  480.     sewer_corridor(l+e,t+e,1,1,lchar);
  481.   }
  482.   if (Current_Dungeon == E_SEWERS) {
  483.     if ((Level->depth == SEWERLEVELS) && (! gamestatusp(COMPLETED_SEWERS))) {
  484.       findspace(&tx,&ty,-1);
  485.       Level->mlist = ((pml) checkmalloc(sizeof(mltype)));
  486.       Level->mlist->next = NULL;
  487.       Level->mlist->m = 
  488.     Level->site[tx][ty].creature = 
  489.       ((pmt) make_creature(ML7+5)); /* The Great Wyrm */
  490.       Level->mlist->m->x = tx;
  491.       Level->mlist->m->y = ty;
  492.     }
  493.   }
  494. }
  495.  
  496.  
  497.  
  498. void sewer_corridor(x,y,dx,dy,locchar)
  499. int x,y,dx,dy;
  500. short locchar;
  501. {
  502.   int continuing = TRUE;
  503.   makedoor(x,y);
  504.   x+=dx;
  505.   y+=dy;
  506.   while(continuing) {
  507.     Level->site[x][y].locchar = locchar;
  508.     if (locchar == WATER)
  509.       Level->site[x][y].p_locf = L_WATER;
  510.     else Level->site[x][y].p_locf = L_NO_OP;
  511.     Level->site[x][y].roomnumber = RS_SEWER_DUCT;
  512.     x+=dx;
  513.     y+=dy;
  514.   if (locchar == WATER)
  515.     continuing = (inbounds(x,y) && 
  516.           ((Level->site[x][y].locchar == WALL) ||
  517.            (Level->site[x][y].locchar == WATER)));
  518.   else
  519.     continuing = (inbounds(x,y) && 
  520.           ((Level->site[x][y].roomnumber == RS_WALLSPACE) ||
  521.            (Level->site[x][y].roomnumber == RS_SEWER_DUCT)));
  522.   }
  523.   if (inbounds(x,y))
  524.     makedoor(x,y);
  525. }
  526.  
  527.  
  528.  
  529.  
  530. void install_specials()
  531. {
  532.   int i,j,x,y;
  533.  
  534.   for(x=0;x<WIDTH;x++)
  535.     for(y=0;y<LENGTH;y++)
  536.       if ((Level->site[x][y].locchar == FLOOR) &&
  537.       (Level->site[x][y].p_locf == L_NO_OP) &&
  538.       (random_range(300) < difficulty())) {
  539.     i = random_range(100);
  540.     if (i < 10) {
  541.       Level->site[x][y].locchar = ALTAR;
  542.       Level->site[x][y].p_locf = L_ALTAR;
  543.       Level->site[x][y].aux = random_range(10);
  544.     }
  545.     else if (i < 20) {
  546.       Level->site[x][y].locchar = WATER;
  547.       Level->site[x][y].p_locf = L_MAGIC_POOL;
  548.     }
  549.     else if (i < 35) {
  550.       Level->site[x][y].locchar = RUBBLE;
  551.       Level->site[x][y].p_locf = L_RUBBLE;
  552.     }
  553.     else if (i < 40) {
  554.       Level->site[x][y].locchar = LAVA;
  555.       Level->site[x][y].p_locf = L_LAVA;
  556.     }
  557.     else if (i < 45) {
  558.       Level->site[x][y].locchar = FIRE;
  559.       Level->site[x][y].p_locf = L_FIRE;
  560.     }
  561.     else if ((i < 50) && (Current_Environment != E_ASTRAL)) {
  562.       Level->site[x][y].locchar = LIFT;
  563.       Level->site[x][y].p_locf = L_LIFT;
  564.     }
  565.     else if ((i < 55) && (Current_Environment != E_VOLCANO)) {
  566.       Level->site[x][y].locchar = HEDGE;
  567.       Level->site[x][y].p_locf = L_HEDGE;
  568.     }
  569.     else if (i < 57) {
  570.       Level->site[x][y].locchar = HEDGE;
  571.       Level->site[x][y].p_locf = L_TRIFID;
  572.     }
  573.     else if (i< 70) {
  574.       Level->site[x][y].locchar = STATUE;
  575.       if (random_range(100) < difficulty()) 
  576.         for (j=0;j<8;j++) {
  577.           if (Level->site[x+Dirs[0][j]][y+Dirs[1][j]].p_locf != L_NO_OP)
  578.         Level->site[x+Dirs[0][j]][y+Dirs[1][j]].locchar = FLOOR;
  579.           Level->site[x+Dirs[0][j]][y+Dirs[1][j]].p_locf = 
  580.         L_STATUE_WAKE;
  581.         }
  582.     }
  583.     else {
  584.       if (Current_Environment == E_VOLCANO) {
  585.         Level->site[x][y].locchar = LAVA;
  586.         Level->site[x][y].p_locf = L_LAVA;
  587.       }
  588.       else if (Current_Environment == E_ASTRAL) {
  589.         if (Level->depth == 1) {
  590.           Level->site[x][y].locchar = RUBBLE;
  591.           Level->site[x][y].p_locf = L_RUBBLE;
  592.         }
  593.         else if (Level->depth == 2) {
  594.           Level->site[x][y].locchar = FIRE;
  595.           Level->site[x][y].p_locf = L_FIRE;
  596.         }
  597.         else if (Level->depth == 3) {
  598.           Level->site[x][y].locchar = WATER;
  599.           Level->site[x][y].p_locf = L_WATER;
  600.         }
  601.         else if (Level->depth == 4) {
  602.           Level->site[x][y].locchar = ABYSS;
  603.           Level->site[x][y].p_locf = L_ABYSS;
  604.         }
  605.       }
  606.       else {
  607.         Level->site[x][y].locchar = WATER;
  608.         Level->site[x][y].p_locf = L_WATER;
  609.       }
  610.     }
  611.       }
  612. }
  613.